﻿using System;
using System.ComponentModel;
using System.IO;
using System.Net;
using InfiniTec.Exchange.Notifications;
using InfiniTec.Threading;

namespace NewMailNotificationExample
{
	internal static class Program
	{
		private const string StateSaverFilename = "notificationstate.bin";

		private static void Main()
		{
			// Ignore any certificate errors
			ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;

			// Setup the adapter which will be used to call into the Exchange WebService  
			using (var adapter = new ExchangeWebServicesAdapter(new Uri("https://nawex001/ews/exchange.asmx"), 
				new NetworkCredential("test2010@netatwork.de", "test\"=!=")))
			using (var listener = new PushNotificationListener())
			{
				Console.Out.WriteLine("Starting Notification Service...");
			/*	Uncomment these lines to request notifications on a secure channel. A certificate must be attached
			    to that port (using netsh http add sslcert) and a port reservation must be created (also using netsh)
			 	listener.ConnectionSecurity = ConnectionSecurity.Secure;
				listener.RelativePath = "PushNotificationsListener";
				listener.Port = 443;*/

				listener.LocalComputerDnsName = "192.168.103.1";
				listener.Start();
				

				SubscriptionCollection subscriptionCollection;

				if (File.Exists(StateSaverFilename + "test"))
				{
					using (var stream = File.OpenRead(StateSaverFilename))
					{
						subscriptionCollection = SubscriptionCollection.Deserialize(stream, adapter, listener);
						subscriptionCollection.SubscriptionRestartCompleted +=
							SubscriptionCollection_OnSubscriptionRestartCompleted;
						subscriptionCollection.SubscriptionRestartProgressChanged +=
							SubscriptionCollection_OnSubscriptionRestartProgressChanged;

						ConfigureSubscriptions(subscriptionCollection);

						subscriptionCollection.RestartAsync();
					}
				}
				else
				{
					// Create a new subscription collection to manage all the subscriptions  
					// Register for a NewMail notification on the inbox of the administrator
					subscriptionCollection = new SubscriptionCollection(adapter, listener)
					                         	{
													
					                         		{new[] {new FolderReference(WellKnownFolderId.Inbox)}, EventTypes.All, SubscriptionType.Push}
					                         	};
					ConfigureSubscriptions(subscriptionCollection);
				}

				Console.Out.WriteLine("Awaiting notifications on {0}", listener.LocalEndpoint);
				Console.Out.WriteLine("Creating subscription");
				
				Console.Out.WriteLine("Waiting for notifications... Hit [Enter] to quit...");
				Console.ReadLine();

				Console.Out.WriteLine("Saving the current state of the notification listener...");
				using (var stream = File.OpenWrite(StateSaverFilename))
				{
					subscriptionCollection.Serialize(stream);
				}
				Console.Out.WriteLine("State saved to {0}", Path.GetFullPath(StateSaverFilename));
			}
		}

		private static void ConfigureSubscriptions(SubscriptionCollection subscriptionCollection)
		{
			foreach (var subscription in subscriptionCollection)
			{
				// Write a line to the console for each new mail received  38:  
				subscription.NewMail += (sender, e) =>
				                        Console.Out.WriteLine(string.Format("{0}: New Mail arrived in your inbox", e.Timestamp));
				//subscription.SwitchSubscriptionType(SubscriptionType.Push);
				subscription.PollIntervalInMinutes = 1;
				subscription.Start();
			}
		}

		private static void SubscriptionCollection_OnSubscriptionRestartProgressChanged(object sender, ProgressChangedEventArgs args)
		{
			Console.Out.WriteLine("Subscription restart {0}% complete.", args.ProgressPercentage);
		}

		private static void SubscriptionCollection_OnSubscriptionRestartCompleted(object sender, AsyncCompletedEventArgs<SubscriptionRestartErrorSummary> args)
		{
			Console.Out.WriteLine("Subscription restart is complete. {0} subscriptions could not be restarted.", args.Result.Errors.Count);
		}
	}
}